home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xdino / Dino2d.c < prev    next >
C/C++ Source or Header  |  1996-04-03  |  22KB  |  640 lines

  1. /*
  2. # X-BASED DINOSAUR CUBE
  3. #
  4. #  Dino2d.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1995 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /* Methods file for Dino2d */
  27.  
  28. #include <stdio.h>
  29. #include <X11/IntrinsicP.h>
  30. #include <X11/Intrinsic.h>
  31. #include <X11/StringDefs.h>
  32. #include <X11/CoreP.h>
  33. #include "DinoP.h"
  34. #include "Dino2dP.h"
  35.  
  36. static void InitializeDino2D();
  37. static void ResizeDino2D();
  38. static void ExposeDino2D();
  39. static Boolean SetValuesDino2D();
  40. static void MoveDino2DTl();
  41. static void MoveDino2DTop();
  42. static void MoveDino2DTr();
  43. static void MoveDino2DLeft();
  44. static void MoveDino2DRight();
  45. static void MoveDino2DBl();
  46. static void MoveDino2DBottom();
  47. static void MoveDino2DBr();
  48. static void ResizePolyhedrons();
  49. static void DrawFrame();
  50. static void DrawOrientLine();
  51.  
  52. static char defaultTranslationsDino2D[] =
  53.   "<KeyPress>q: Quit()\n\
  54.    Ctrl<KeyPress>C: Quit()\n\
  55.    <KeyPress>Home: MoveTl()\n\
  56.    <KeyPress>KP_7: MoveTl()\n\
  57.    <KeyPress>R7: MoveTl()\n\
  58.    <KeyPress>Up: MoveTop()\n\
  59.    <KeyPress>KP_8: MoveTop()\n\
  60.    <KeyPress>R8: MoveTop()\n\
  61.    <KeyPress>Prior: MoveTr()\n\
  62.    <KeyPress>KP_9: MoveTr()\n\
  63.    <KeyPress>R9: MoveTr()\n\
  64.    <KeyPress>Left: MoveLeft()\n\
  65.    <KeyPress>KP_4: MoveLeft()\n\
  66.    <KeyPress>R10: MoveLeft()\n\
  67.    <KeyPress>Right: MoveRight()\n\
  68.    <KeyPress>KP_6: MoveRight()\n\
  69.    <KeyPress>R12: MoveRight()\n\
  70.    <KeyPress>End: MoveBl()\n\
  71.    <KeyPress>KP_1: MoveBl()\n\
  72.    <KeyPress>R1: MoveBl()\n\
  73.    <KeyPress>Down: MoveBottom()\n\
  74.    <KeyPress>KP_2: MoveBottom()\n\
  75.    <KeyPress>R14: MoveBottom()\n\
  76.    <KeyPress>Next: MoveBr()\n\
  77.    <KeyPress>KP_3: MoveBr()\n\
  78.    <KeyPress>R3: MoveBr()\n\
  79.    <Btn1Down>: Select()\n\
  80.    <Btn1Up>: Release()\n\
  81.    <KeyPress>p: Practice()\n\
  82.    <Btn2Down>(2+): Practice()\n\
  83.    <Btn2Down>: PracticeMaybe()\n\
  84.    <KeyPress>r: Randomize()\n\
  85.    <Btn3Down>(2+): Randomize()\n\
  86.    <Btn3Down>: RandomizeMaybe()\n\
  87.    <KeyPress>g: Get()\n\
  88.    <KeyPress>w: Write()\n\
  89.    <KeyPress>u: Undo()\n\
  90.    <KeyPress>s: Solve()\n\
  91.    <KeyPress>o: Orientize()\n\
  92.    <KeyPress>2: Period2()\n\
  93.    <KeyPress>3: Period3()\n\
  94.    <KeyPress>b: Both()";
  95.  
  96. static XtActionsRec actionsListDino2D[] =
  97. {
  98.   {"Quit", (XtActionProc) QuitDino},
  99.   {"MoveTl", (XtActionProc) MoveDino2DTl},
  100.   {"MoveTop", (XtActionProc) MoveDino2DTop},
  101.   {"MoveTr", (XtActionProc) MoveDino2DTr},
  102.   {"MoveLeft", (XtActionProc) MoveDino2DLeft},
  103.   {"MoveRight", (XtActionProc) MoveDino2DRight},
  104.   {"MoveBl", (XtActionProc) MoveDino2DBl},
  105.   {"MoveBottom", (XtActionProc) MoveDino2DBottom},
  106.   {"MoveBr", (XtActionProc) MoveDino2DBr},
  107.   {"Select", (XtActionProc) SelectDino},
  108.   {"Release", (XtActionProc) ReleaseDino},
  109.   {"Practice", (XtActionProc) PracticeDino},
  110.   {"PracticeMaybe", (XtActionProc) PracticeDinoMaybe},
  111.   {"Randomize", (XtActionProc) RandomizeDino},
  112.   {"RandomizeMaybe", (XtActionProc) RandomizeDinoMaybe},
  113.   {"Get", (XtActionProc) GetDino},
  114.   {"Write", (XtActionProc) WriteDino},
  115.   {"Undo", (XtActionProc) UndoDino},
  116.   {"Solve", (XtActionProc) SolveDino},
  117.   {"Orientize", (XtActionProc) OrientizeDino},
  118.   {"Period2", (XtActionProc) Period2ModeDino},
  119.   {"Period3", (XtActionProc) Period3ModeDino},
  120.   {"Both", (XtActionProc) BothModeDino}
  121. };
  122.  
  123. static XtResource resourcesDino2D[] =
  124. {
  125.   {XtNfaceColor0, XtCLabel, XtRString, sizeof(String),
  126.    XtOffset(DinoWidget, dino.faceName[0]), XtRString, "Orange"},
  127.   {XtNfaceColor1, XtCLabel, XtRString, sizeof(String),
  128.    XtOffset(DinoWidget, dino.faceName[1]), XtRString, "Pink"},
  129.   {XtNfaceColor2, XtCLabel, XtRString, sizeof(String),
  130.    XtOffset(DinoWidget, dino.faceName[2]), XtRString, "White"},
  131.   {XtNfaceColor3, XtCLabel, XtRString, sizeof(String),
  132.    XtOffset(DinoWidget, dino.faceName[3]), XtRString, "Violet"},
  133.   {XtNfaceColor4, XtCLabel, XtRString, sizeof(String),
  134.    XtOffset(DinoWidget, dino.faceName[4]), XtRString, "Yellow"},
  135.   {XtNfaceColor5, XtCLabel, XtRString, sizeof(String),
  136.    XtOffset(DinoWidget, dino.faceName[5]), XtRString, "Blue"},
  137.   {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  138.    XtOffset(DinoWidget, dino.foreground), XtRString, XtDefaultForeground},
  139.   {XtNpieceBorder, XtCColor, XtRPixel, sizeof(Pixel),
  140.    XtOffset(DinoWidget, dino.borderColor), XtRString, XtDefaultForeground},
  141.   {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
  142.    XtOffset(DinoWidget, core.width), XtRString, "300"},
  143.   {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
  144.    XtOffset(DinoWidget, core.height), XtRString, "400"},
  145.   {XtNmode, XtCMode, XtRInt, sizeof(int),
  146.    XtOffset(DinoWidget, dino.mode), XtRString, "3"}, /*DEFAULTMODE*/
  147.   {XtNorient, XtCOrient, XtRBoolean, sizeof(Boolean),
  148.    XtOffset(DinoWidget, dino.orient), XtRString, "FALSE"}, /* DEFAULTORIENT */
  149.   {XtNmono, XtCMono, XtRBoolean, sizeof(Boolean),
  150.    XtOffset(DinoWidget, dino.mono), XtRString, "FALSE"},
  151.   {XtNface, XtCFace, XtRInt, sizeof(int),
  152.    XtOffset(DinoWidget, dino.currentFace), XtRString, "-1"},
  153.   {XtNpos, XtCPos, XtRInt, sizeof(int),
  154.    XtOffset(DinoWidget, dino.currentPosition), XtRString, "-1"},
  155.   {XtNdirection, XtCDirection, XtRInt, sizeof(int),
  156.    XtOffset(DinoWidget, dino.currentDirection), XtRString, "-1"},
  157.   {XtNstyle, XtCStyle, XtRInt, sizeof(int),
  158.    XtOffset(DinoWidget, dino.style), XtRString, "-1"},
  159.   {XtNpractice, XtCBoolean, XtRBoolean, sizeof(Boolean),
  160.    XtOffset(DinoWidget, dino.practice), XtRString, "FALSE"},
  161.   {XtNstart, XtCBoolean, XtRBoolean, sizeof(Boolean),
  162.    XtOffset(DinoWidget, dino.started), XtRString, "FALSE"},
  163.   {XtNselectCallback, XtCCallback, XtRCallback, sizeof(caddr_t),
  164.    XtOffset(DinoWidget, dino.select), XtRCallback, NULL}
  165. };
  166.  
  167. Dino2DClassRec dino2dClassRec =
  168. {
  169.   {
  170.     (WidgetClass) &dinoClassRec,    /* superclass */
  171.     "Dino2D",                /* class name */
  172.     sizeof(Dino2DRec),            /* widget size */
  173.     NULL,                /* class initialize */
  174.     NULL,                /* class part initialize */
  175.     FALSE,                /* class inited */
  176.     InitializeDino2D,            /* initialize */
  177.     NULL,                /* initialize hook */
  178.     XtInheritRealize,            /* realize */
  179.     actionsListDino2D,            /* actions */
  180.     XtNumber(actionsListDino2D),    /* num actions */
  181.     resourcesDino2D,            /* resources */
  182.     XtNumber(resourcesDino2D),        /* num resources */
  183.     NULLQUARK,                /* xrm class */
  184.     TRUE,                /* compress motion */
  185.     TRUE,                /* compress exposure */
  186.     TRUE,                /* compress enterleave */
  187.     TRUE,                /* visible interest */
  188.     NULL,                /* destroy */
  189.     ResizeDino2D,            /* resize */
  190.     ExposeDino2D,            /* expose */
  191.     SetValuesDino2D,            /* set values */
  192.     NULL,                /* set values hook */
  193.     XtInheritSetValuesAlmost,        /* set values almost */
  194.     NULL,                /* get values hook */
  195.     XtInheritAcceptFocus,        /* accept focus */
  196.     XtVersion,                /* version */
  197.     NULL,                /* callback private */
  198.     defaultTranslationsDino2D,        /* tm table */
  199.     NULL,                /* query geometry */
  200.     NULL,                /* display accelerator */
  201.     NULL                /* extension */
  202.   },
  203.   {
  204.     0                    /* ignore */
  205.   },
  206.   {
  207.     0                    /* ignore */
  208.   }
  209. };
  210.  
  211. WidgetClass dino2dWidgetClass = (WidgetClass) &dino2dClassRec;
  212.  
  213. static int planeToCube[MAXRECT] = {6, 0, 6, 1, 2, 3, 6, 4, 6, 6, 5, 6};
  214. static int cubeToPlane[MAXFACES] = {1, 3, 4, 5, 7, 10};
  215. static XPoint triangleUnit[MAXORIENT][4] = {
  216.     {{2, 0},  {-1,  1}, {-1, -1}, { 2,  0}},
  217.     {{3, 2},  {-1, -1}, { 1, -1}, { 0,  2}},
  218.     {{1, 3},  { 1, -1}, { 1,  1}, {-2,  0}},
  219.     {{0, 1},  { 1,  1}, {-1,  1}, { 0, -2}}
  220.   },
  221.   letterUnit[MAXORIENT] = {{1, 0}, {2, 1}, {1, 2}, {0, 1}};
  222. static XPoint triangleList[MAXORIENT][4],
  223.   letterList[MAXORIENT], offsetList[MAXORIENT];
  224.  
  225. static void InitializeDino2D(request, new)
  226.   Widget request, new;
  227. {
  228.   Dino2DWidget w = (Dino2DWidget) new;
  229.  
  230.   w->dino.dim = 2;
  231.   ResizeDino2D(w);
  232. }
  233.  
  234. static void ResizeDino2D(w)
  235.   Dino2DWidget w;
  236. {
  237.   w->dino.delta = 2;
  238.   w->dino.vertical = (w->core.height >= w->core.width);
  239.   if (w->dino.vertical)
  240.     w->dino2d.faceLength = MIN(w->core.height / MAXY, w->core.width / MAXX);
  241.   else
  242.     w->dino2d.faceLength = MIN(w->core.height / MAXX, w->core.width / MAXY);
  243.   w->dino2d.faceLength = MAX(w->dino2d.faceLength - w->dino.delta - 1, 0);
  244.   w->dino2d.diamondLength = w->dino2d.faceLength - w->dino.delta;
  245.   w->dino2d.viewLength = w->dino2d.faceLength + w->dino.delta;
  246.   if (w->dino.vertical) {
  247.     w->dino.puzzleSize.x = MAXX * (w->dino2d.viewLength - 1) +
  248.       w->dino.delta;
  249.     w->dino.puzzleSize.y = MAXY * (w->dino2d.viewLength - 1) +
  250.       w->dino.delta;
  251.   } else {
  252.     w->dino.puzzleSize.x = MAXY * (w->dino2d.viewLength - 1) +
  253.       w->dino.delta;
  254.     w->dino.puzzleSize.y = MAXX * (w->dino2d.viewLength - 1) +
  255.       w->dino.delta;
  256.   }
  257.   w->dino.puzzleOffset.x = ((int) w->core.width - w->dino.puzzleSize.x)
  258.     / 2;
  259.   w->dino.puzzleOffset.y = ((int) w->core.height - w->dino.puzzleSize.y)
  260.     / 2;
  261.   ResizePolyhedrons(w);
  262. }
  263.  
  264. static void ExposeDino2D(new, event, region)
  265.   Widget new;
  266.   XEvent *event;
  267.   Region region; /* Not used */
  268. {
  269.   Dino2DWidget w = (Dino2DWidget) new;
  270.  
  271.   if (w->core.visible) {
  272.     DrawFrame(w, w->dino.puzzleGC);
  273.     DrawAllPolyhedrons((DinoWidget) w);
  274.   }
  275. }
  276.  
  277. static Boolean SetValuesDino2D(current, request, new)
  278.   Widget current, request, new;
  279. {
  280.   Dino2DWidget c = (Dino2DWidget) current, w = (Dino2DWidget) new;
  281.   Boolean redraw = FALSE;
  282.  
  283.   if (w->dino2d.diamondLength != c->dino2d.diamondLength) {
  284.     ResizeDino2D(w);
  285.     redraw = TRUE;
  286.   }
  287.   return (redraw);
  288. }
  289.  
  290. static void MoveDino2DTl(w, event, args, nArgs)
  291.   Dino2DWidget w;
  292.   XEvent *event;
  293.   char *args[];
  294.   int nArgs;
  295. {
  296.   MoveDinoInput((DinoWidget) w, event->xbutton.x, event->xbutton.y, TL,
  297.     (int) (event->xkey.state & (ShiftMask | LockMask)),
  298.     (int) (event->xkey.state & ControlMask),
  299.     (int) (event->xkey.state &
  300.       (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)));
  301. }
  302.  
  303. static void MoveDino2DTop(w, event, args, nArgs)
  304.   Dino2DWidget w;
  305.   XEvent *event;
  306.   char *args[];
  307.   int nArgs;
  308. {
  309.   MoveDinoInput((DinoWidget) w, event->xbutton.x, event->xbutton.y, TOP,
  310.     (int) (event->xkey.state & (ShiftMask | LockMask)),
  311.     (int) (event->xkey.state & ControlMask),
  312.     (int) (event->xkey.state &
  313.       (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)));
  314. }
  315.  
  316. static void MoveDino2DTr(w, event, args, nArgs)
  317.   Dino2DWidget w;
  318.   XEvent *event;
  319.   char *args[];
  320.   int nArgs;
  321. {
  322.   MoveDinoInput((DinoWidget) w, event->xbutton.x, event->xbutton.y, TR,
  323.     (int) (event->xkey.state & (ShiftMask | LockMask)),
  324.     (int) (event->xkey.state & ControlMask),
  325.     (int) (event->xkey.state &
  326.       (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)));
  327. }
  328.  
  329. static void MoveDino2DLeft(w, event, args, nArgs)
  330.   Dino2DWidget w;
  331.   XEvent *event;
  332.   char *args[];
  333.   int nArgs;
  334. {
  335.   MoveDinoInput((DinoWidget) w, event->xbutton.x, event->xbutton.y, LEFT,
  336.     (int) (event->xkey.state & (ShiftMask | LockMask)),
  337.     (int) (event->xkey.state & ControlMask),
  338.     (int) (event->xkey.state &
  339.       (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)));
  340. }
  341.  
  342. static void MoveDino2DRight(w, event, args, nArgs)
  343.   Dino2DWidget w;
  344.   XEvent *event;
  345.   char *args[];
  346.   int nArgs;
  347. {
  348.   MoveDinoInput((DinoWidget) w, event->xbutton.x, event->xbutton.y, RIGHT,
  349.     (int) (event->xkey.state & (ShiftMask | LockMask)),
  350.     (int) (event->xkey.state & ControlMask),
  351.     (int) (event->xkey.state &
  352.       (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)));
  353. }
  354.  
  355. static void MoveDino2DBl(w, event, args, nArgs)
  356.   Dino2DWidget w;
  357.   XEvent *event;
  358.   char *args[];
  359.   int nArgs;
  360. {
  361.   MoveDinoInput((DinoWidget) w, event->xbutton.x, event->xbutton.y, BL,
  362.     (int) (event->xkey.state & (ShiftMask | LockMask)),
  363.     (int) (event->xkey.state & ControlMask),
  364.     (int) (event->xkey.state &
  365.       (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)));
  366. }
  367.  
  368. static void MoveDino2DBottom(w, event, args, nArgs)
  369.   Dino2DWidget w;
  370.   XEvent *event;
  371.   char *args[];
  372.   int nArgs;
  373. {
  374.   MoveDinoInput((DinoWidget) w, event->xbutton.x, event->xbutton.y, BOTTOM,
  375.     (int) (event->xkey.state & (ShiftMask | LockMask)),
  376.     (int) (event->xkey.state & ControlMask),
  377.     (int) (event->xkey.state &
  378.       (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)));
  379. }
  380.  
  381. static void MoveDino2DBr(w, event, args, nArgs)
  382.   Dino2DWidget w;
  383.   XEvent *event;
  384.   char *args[];
  385.   int nArgs;
  386. {
  387.   MoveDinoInput((DinoWidget) w, event->xbutton.x, event->xbutton.y, BR,
  388.     (int) (event->xkey.state & (ShiftMask | LockMask)),
  389.     (int) (event->xkey.state & ControlMask),
  390.     (int) (event->xkey.state &
  391.       (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)));
  392. }
  393.  
  394. static void ResizePolyhedrons(w)
  395.   Dino2DWidget w;
  396. {
  397.   int i, j;
  398.  
  399.   w->dino.orientLineLength = w->dino2d.diamondLength / 3;
  400.   w->dino.letterOffset.x = -2;
  401.   w->dino.letterOffset.y = 4;
  402.   for (i = 0; i < MAXORIENT; i++) {
  403.     for (j = 0; j <= 3; j++) {
  404.       triangleList[i][j].x = triangleUnit[i][j].x *
  405.         (w->dino2d.diamondLength / 2 - 2 * w->dino.delta);
  406.       triangleList[i][j].y = triangleUnit[i][j].y *
  407.         (w->dino2d.diamondLength / 2 - 2 * w->dino.delta);
  408.     }
  409.     if (letterUnit[i].x == 0)
  410.       letterList[i].x = w->dino2d.diamondLength / 5 +
  411.         w->dino.letterOffset.x;
  412.     else if (letterUnit[i].x == 1)
  413.       letterList[i].x = w->dino2d.diamondLength / 2 - 1 +
  414.         w->dino.letterOffset.x;
  415.     else if (letterUnit[i].x == 2)
  416.       letterList[i].x = 4 * w->dino2d.diamondLength / 5 - 2 +
  417.         w->dino.letterOffset.x;
  418.     if (letterUnit[i].y == 0)
  419.       letterList[i].y = w->dino2d.diamondLength / 5 + 2 +
  420.         w->dino.letterOffset.y;
  421.     else if (letterUnit[i].y == 1)
  422.       letterList[i].y = w->dino2d.diamondLength / 2 - 1 +
  423.         w->dino.letterOffset.y;
  424.     else if (letterUnit[i].y == 2)
  425.       letterList[i].y = 4 * w->dino2d.diamondLength / 5 - 3 +
  426.         w->dino.letterOffset.y;
  427.  
  428.     if (triangleUnit[i][0].x == 0)
  429.       offsetList[i].x = w->dino.delta - 1;
  430.     else if (triangleUnit[i][0].x == 1)
  431.       offsetList[i].x = 2 * w->dino.delta - 1;
  432.     else if (triangleUnit[i][0].x == 2)
  433.       offsetList[i].x = w->dino2d.diamondLength -
  434.         2 * w->dino.delta - 2;
  435.     else if (triangleUnit[i][0].x == 3)
  436.       offsetList[i].x = w->dino2d.diamondLength - w->dino.delta - 2;
  437.     if (triangleUnit[i][0].y == 0)
  438.       offsetList[i].y = w->dino.delta - 2;
  439.     else if (triangleUnit[i][0].y == 1)
  440.       offsetList[i].y = 2 * w->dino.delta - 1;
  441.     else if (triangleUnit[i][0].y == 2)
  442.       offsetList[i].y = w->dino2d.diamondLength -
  443.         2 * w->dino.delta - 2;
  444.     else if (triangleUnit[i][0].y == 3)
  445.       offsetList[i].y = w->dino2d.diamondLength - w->dino.delta - 1;
  446.    }
  447. }
  448.  
  449. int SelectPolyhedrons2D(w, x, y, face, position)
  450.   Dino2DWidget w;
  451.   int x, y;
  452.   int *face, *position;
  453. {
  454.   int faceX, faceY, i, j;
  455.  
  456.   x -= w->dino.puzzleOffset.x;
  457.   y -= w->dino.puzzleOffset.y;
  458.   faceX = x / w->dino2d.viewLength;
  459.   faceY = y / w->dino2d.viewLength;
  460.   i = x - faceX * w->dino2d.viewLength;
  461.   j = y - faceY * w->dino2d.viewLength;
  462.   if (i + j < w->dino2d.viewLength && i - j > 0)
  463.     *position = TOP;
  464.   else if (i - j > 0 && i + j > w->dino2d.viewLength)
  465.     *position = RIGHT;
  466.   else if (i + j > w->dino2d.viewLength && j - i > 0)
  467.     *position = BOTTOM;
  468.   else if (j - i > 0 && i + j < w->dino2d.viewLength)
  469.     *position = LEFT;
  470.   else
  471.     *position = MAXORIENT;
  472.   if ((faceX != 1 && faceY != 1) ||
  473.       (faceX >= 3 && w->dino.vertical) ||
  474.       (faceY >= 3 && !w->dino.vertical))
  475.     return FALSE;
  476.   *face = planeToCube[faceX + faceY * MAXX];
  477.   if (*position != MAXORIENT && faceX == 3) {
  478.     *face = MAXFACES - 1;
  479.     *position = (*position + HALF) % MAXORIENT;
  480.   } else
  481.     *position %= MAXORIENT;
  482.   return TRUE;
  483. }
  484.  
  485. int NarrowSelection2D(w, face, direction)
  486.   Dino2DWidget w;
  487.   int *face;
  488.   int *direction;
  489. {
  490.   if (*face == MAXFACES - 1 && *direction < MAXORIENT && !w->dino.vertical) {
  491.     if (*direction < MAXORIENT)
  492.       *direction = (*direction + HALF) % MAXORIENT;
  493.     else if (*direction >= 2 * MAXORIENT)
  494.       *direction = 2 * MAXORIENT + (*direction + HALF) % MAXORIENT;
  495.   }
  496.   return TRUE;
  497. }
  498.  
  499. static void DrawFrame(w, gc)
  500.   Dino2DWidget w;
  501.   GC gc;
  502. {
  503.   int i;
  504.   XPoint pos[MAXXY + 1], letters;
  505.   
  506.   for (i = 0; i <= MAXXY; i++) {
  507.     pos[i].x = i * w->dino2d.viewLength + w->dino.puzzleOffset.x;
  508.     pos[i].y = i * w->dino2d.viewLength + w->dino.puzzleOffset.y;
  509.   }
  510.   XDrawLine(XtDisplay(w), XtWindow(w), gc,
  511.     pos[1].x, pos[0].y, pos[2].x, pos[0].y);
  512.   XDrawLine(XtDisplay(w), XtWindow(w), gc,
  513.     pos[3].x, pos[1].y, pos[3].x, pos[2].y);
  514.   XDrawLine(XtDisplay(w), XtWindow(w), gc,
  515.     pos[1].x, pos[3].y, pos[2].x, pos[3].y);
  516.   XDrawLine(XtDisplay(w), XtWindow(w), gc,
  517.     pos[0].x, pos[1].y, pos[0].x, pos[2].y);
  518.   letters.x = pos[0].x + w->dino2d.viewLength / 2 - w->dino.delta;
  519.   letters.y = pos[0].y + w->dino2d.viewLength / 2;
  520.   XDrawString(XtDisplay(w), XtWindow(w), gc,
  521.     (int) (letters.x + 5 * w->dino.letterOffset.x),
  522.     (int) (letters.y + w->dino.letterOffset.y), "Front", 5);
  523.   letters.x = pos[2].x + w->dino2d.viewLength / 2 - w->dino.delta;
  524.   letters.y = pos[2].y + w->dino2d.viewLength / 2;
  525.   XDrawString(XtDisplay(w), XtWindow(w), gc,
  526.     (int) (letters.x + 4 * w->dino.letterOffset.x),
  527.     (int) (letters.y + w->dino.letterOffset.y), "Back", 4);
  528.   if (w->dino.vertical) {
  529.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  530.       pos[1].x, pos[0].y, pos[1].x, pos[4].y);
  531.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  532.       pos[2].x, pos[0].y, pos[2].x, pos[4].y);
  533.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  534.       pos[0].x, pos[1].y, pos[3].x, pos[1].y);
  535.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  536.       pos[0].x, pos[2].y, pos[3].x, pos[2].y);
  537.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  538.       pos[1].x, pos[4].y, pos[2].x, pos[4].y);
  539.   } else {
  540.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  541.       pos[0].x, pos[1].y, pos[4].x, pos[1].y);
  542.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  543.       pos[0].x, pos[2].y, pos[4].x, pos[2].y);
  544.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  545.       pos[1].x, pos[0].y, pos[1].x, pos[3].y);
  546.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  547.       pos[2].x, pos[0].y, pos[2].x, pos[3].y);
  548.     XDrawLine(XtDisplay(w), XtWindow(w), gc,
  549.       pos[4].x, pos[1].y, pos[4].x, pos[2].y);
  550.   }
  551. }   
  552.  
  553. void DrawTriangle2D(w, face, position, offset)
  554.   Dino2DWidget w;
  555.   int face, position, offset;
  556. {
  557.   int dx, dy, letterX, letterY, newSide, orient;
  558.  
  559.   orient = w->dino.cubeLoc[face][position].rotation;
  560.   if (w->dino.vertical || face != MAXFACES - 1) {
  561.     dx = (cubeToPlane[face] % MAXX) * w->dino2d.viewLength;
  562.     dy = (cubeToPlane[face] / MAXX) * w->dino2d.viewLength;
  563.     newSide = position;
  564.   } else {
  565.     dx = (cubeToPlane[face] / MAXX) * w->dino2d.viewLength;
  566.     dy = (cubeToPlane[face] % MAXX) * w->dino2d.viewLength;
  567.     newSide = (position + HALF) % STRT;
  568.     orient = (orient + HALF) % STRT;
  569.   }
  570.   dx += w->dino.puzzleOffset.x + 2 * w->dino.delta;
  571.   dy += w->dino.puzzleOffset.y + 2 * w->dino.delta;
  572.   letterX = dx + letterList[newSide].x - 1;
  573.   letterY = dy + letterList[newSide].y;
  574.   triangleList[newSide][0].x = offsetList[newSide].x + dx;
  575.   triangleList[newSide][0].y = offsetList[newSide].y + dy;
  576.   if (offset) {
  577.     XFillPolygon(XtDisplay(w), XtWindow(w),
  578.       w->dino.borderGC,
  579.       triangleList[newSide], 3, Convex, CoordModePrevious);
  580.     XDrawLines(XtDisplay(w), XtWindow(w),
  581.       w->dino.faceGC[w->dino.cubeLoc[face][position].face],
  582.       triangleList[newSide], 4, CoordModePrevious);
  583.   } else {
  584.     XFillPolygon(XtDisplay(w), XtWindow(w),
  585.       w->dino.faceGC[w->dino.cubeLoc[face][position].face],
  586.       triangleList[newSide], 3, Convex, CoordModePrevious);
  587.     XDrawLines(XtDisplay(w), XtWindow(w),
  588.       w->dino.borderGC, triangleList[newSide], 4, CoordModePrevious);
  589.   }
  590.   if (w->dino.depth == 1 || w->dino.mono) {
  591.     char buf[2];
  592.  
  593.     (void) sprintf(buf, "%c",
  594.              w->dino.faceName[w->dino.cubeLoc[face][position].face][0]);
  595.     XDrawString(XtDisplay(w), XtWindow(w), w->dino.inverseGC,
  596.       letterX, letterY, buf, 1);
  597.   }
  598.   if (w->dino.orient)
  599.     DrawOrientLine(w, orient + 2 * MAXORIENT,
  600.       letterX - w->dino.letterOffset.x, letterY - w->dino.letterOffset.y);
  601. }
  602.  
  603. static void DrawOrientLine(w, orient, dx, dy)
  604.   Dino2DWidget w;
  605.   int orient, dx, dy;
  606. {
  607.   switch (orient) {
  608.     case TOP:
  609.       XDrawLine(XtDisplay(w), XtWindow(w), w->dino.inverseGC,
  610.                 dx,
  611.                 dy - w->dino.delta,
  612.                 dx,
  613.                 dy - w->dino.delta - w->dino.orientLineLength / 2);
  614.       return;
  615.     case RIGHT:
  616.       XDrawLine(XtDisplay(w), XtWindow(w), w->dino.inverseGC,
  617.                 dx + w->dino.delta,
  618.                 dy,
  619.                 dx + w->dino.delta + w->dino.orientLineLength / 2,
  620.                 dy);
  621.       return;
  622.     case BOTTOM:
  623.       XDrawLine(XtDisplay(w), XtWindow(w), w->dino.inverseGC,
  624.                 dx,
  625.                 dy + w->dino.delta,
  626.                 dx,
  627.                 dy + w->dino.delta + w->dino.orientLineLength / 2);
  628.       return;
  629.     case LEFT:
  630.       XDrawLine(XtDisplay(w), XtWindow(w), w->dino.inverseGC,
  631.                 dx - w->dino.delta,
  632.                 dy,
  633.                 dx - w->dino.delta - w->dino.orientLineLength / 2,
  634.                 dy);
  635.       return;
  636.     default:
  637.       (void) printf("DrawOrientLine: orient %d\n", orient);
  638.   }
  639. }
  640.